// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: declaration of CXFormsParse.
//   $Id$


// Parse.h: handles parsing outside of the root elements.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PARSE_H__683CBC24_4877_4581_BCAB_7816CE1E41BE__INCLUDED_)
#define AFX_PARSE_H__683CBC24_4877_4581_BCAB_7816CE1E41BE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#include <map>
#include <list>
typedef HRESULT (_stdcall* ParseFunction)(VARIANT,LPVOID*);
typedef std::map<CComBSTR,LPVOID*> CMapBSTRToVoidPtr;
typedef std::pair<CComBSTR,LPVOID*> CPairCComBSTRLPVoid;

typedef std::map<CComBSTR,ParseFunction> CMapBSTRToParseFunction;
typedef std::pair<CComBSTR,ParseFunction> CPairCComBSTRParseFunction;

typedef std::map<CComBSTR,CMapStringToPtr*> CMapBSTRToStringMap;
typedef std::pair<CComBSTR,CMapStringToPtr*> CPairCComBSTRStringMap;

typedef std::list<CPairCComBSTRLPVoid> CListCComBSTRLPVoidPair;

/*
 * This is the base class for all parsing
 */

	namespace XFormsParse
	{
		HRESULT __stdcall parseXSDDouble(VARIANT vtStr, double *d);
		HRESULT __stdcall parseXSDLong(VARIANT vtStr ,LPVOID* vdTok);
		HRESULT __stdcall parseXSDBoolean(VARIANT vtStr ,LPVOID* vdTok);
	}

class CImpl;

class CXFormsParse
{
public:
	//TODO:
	//	compulsoryAttributesList. - requires new
	//		param on addAttributeCheck default value = false;
	//	make m_AttributeParseFunctions and m_AttributeParseMaps dynamic.
	//	as they are not always needed.
	CXFormsParse(CImpl* pImpl);
	virtual ~CXFormsParse();
	virtual HRESULT Parse(IHTMLElement* pElem, CImpl* pImpl);

protected:
	inline void addAttributeCheck(BSTR psName, LPVOID* psValue,bool bCompulsory = false);
	inline void addAttributeCheck(BSTR psName, ULONG* pulValue,bool bCompulsory = false);
	inline void addAttributeCheck(BSTR psName, BSTR * psValue,bool bCompulsory = false);
	inline void addAttributeCheck(BSTR psName, LPVOID* psValue,HRESULT (_stdcall*pFunc)(VARIANT,LPVOID*),bool bCompulsory = false);
	inline void addAttributeCheck(BSTR psName, LPVOID psValue,HRESULT (_stdcall*pFunc)(VARIANT,LPVOID*),bool bCompulsory = false);
	inline void addAttributeCheck(BSTR psName, double *pdValue, HRESULT(_stdcall *pFunc)(VARIANT, double*), bool bCompulsory = false);
	inline void addAttributeCheck(BSTR psName, LPVOID* psValue,CMapStringToPtr *theMap,bool bCompulsory = false);
	bool m_bCheckElements;
	virtual HRESULT SetAttributes(IHTMLElement *pElem, CImpl* pImpl);
	HRESULT CheckAttribute(CComBSTR& sName,VARIANT v,LPVOID* pDest);
	virtual void CheckElement(IHTMLElement *pElem, BSTR bstrTag, CImpl* pImpl);

	// Pointer to the m_sTextContent [or m_sContent: see bug 261] member variable
	// of the pImpl. This is initialised to 0 in the base ctor and only set if the
	// pImpl wants content (inserted just like addAttributeCheck).
	BSTR *m_psImplContent;
private:
	CListCComBSTRLPVoidPair m_PossibleAttributeList;
	CMapBSTRToParseFunction m_AttributeParseFunctions;
	CMapBSTRToStringMap m_AttributeParseMaps;
	CListCComBSTRLPVoidPair m_CompulsoryAttributeList;

	HRESULT SetElements(IHTMLElement *pElem, CImpl* pImpl);
	
};

inline void CXFormsParse::addAttributeCheck(BSTR psName, LPVOID* psValue,bool bCompulsory)
{
	CListCComBSTRLPVoidPair * pListToUse = NULL;
	if(bCompulsory)
	{
		pListToUse = &m_CompulsoryAttributeList;
	}
	else
	{
		pListToUse = &m_PossibleAttributeList;
	}
	
	pListToUse->push_back(CPairCComBSTRLPVoid(psName,reinterpret_cast<void**>(psValue)));
}

inline void CXFormsParse::addAttributeCheck(BSTR psName, BSTR * psValue,bool bCompulsory)
{
	addAttributeCheck( psName,  reinterpret_cast<void**>(psValue),bCompulsory);
	
}
inline void CXFormsParse::addAttributeCheck(BSTR psName, ULONG* pulValue,bool bCompulsory)
{
	addAttributeCheck(psName,(LPVOID*)pulValue,XFormsParse::parseXSDLong,bCompulsory);
}

inline void CXFormsParse::addAttributeCheck(BSTR psName, LPVOID* psValue,HRESULT (_stdcall*pFunc)(VARIANT,LPVOID*),bool bCompulsory)
{
	addAttributeCheck( psName,  psValue,bCompulsory);
	m_AttributeParseFunctions.insert(CPairCComBSTRParseFunction(psName,pFunc));
}

inline void CXFormsParse::addAttributeCheck(BSTR psName, double *pdValue, HRESULT(_stdcall *pFunc)(VARIANT, double*), bool bCompulsory)
{
	addAttributeCheck( psName,  reinterpret_cast<void**>(pdValue),bCompulsory);

	m_AttributeParseFunctions.insert(CPairCComBSTRParseFunction(psName,reinterpret_cast<ParseFunction>(pFunc)));
}

inline void CXFormsParse::addAttributeCheck(BSTR psName, LPVOID* psValue,CMapStringToPtr * theMap,bool bCompulsory)
{
	addAttributeCheck( psName, psValue,bCompulsory);
	m_AttributeParseMaps.insert(CPairCComBSTRStringMap(psName,theMap));
}


#endif // !defined(AFX_PARSE_H__683CBC24_4877_4581_BCAB_7816CE1E41BE__INCLUDED_)
